package com.design.BuilderMode.mode;


import lombok.ToString;
import org.springframework.util.StringUtils;

@ToString
public class ThreadConfig {

    /**
     * 核心线程默认值
     */
    private static final Integer CORE_POOL_SIZE = 4;

    /**
     * 线程名称
     */
    private String threadName;

    /**
     * 核心线程数
     */
    private Integer corePoolSize = CORE_POOL_SIZE;
    /**
     * 最大线程数
     */
    private Integer maxPoolSize;
    /**
     * 队列数
     */
    private Integer queueCapacity;

    /**
     * 当线程空闲时间达到keepAliveTime，该线程会退出
     */
    private Integer keepAliveTime;

    /**
     * 是否允许核心线程数空闲时退出
     */
    private boolean allowCoreThreadTimeout;

    private ThreadConfig(ThreadConfig.Builder builder) {
        this.threadName = builder.threadName;
        if(null != builder.corePoolSize){
            this.corePoolSize = builder.corePoolSize;
        }
        this.maxPoolSize = builder.maxPoolSize;
        this.queueCapacity = builder.queueCapacity;
        this.keepAliveTime = builder.keepAliveTime;
        this.allowCoreThreadTimeout = builder.allowCoreThreadTimeout;
    }

    /**
     * 使用静态方法替代new
     * @return
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * 内部静态Builder类
     */
    public static class Builder{

        /**
         * 线程名称
         */
        private String threadName;

        /**
         * 核心线程数
         */
        private Integer corePoolSize;
        /**
         * 最大线程数
         */
        private Integer maxPoolSize;
        /**
         * 队列数
         */
        private Integer queueCapacity;

        /**
         * 当线程空闲时间达到keepAliveTime，该线程会退出
         */
        private Integer keepAliveTime;

        /**
         * 是否允许核心线程数空闲时退出
         */
        private boolean allowCoreThreadTimeout;

        public ThreadConfig builder() throws IllegalAccessException {
            if (StringUtils.isEmpty(threadName)) {
                throw new IllegalAccessException("线程名不能为空");
            }
            if(corePoolSize != null && maxPoolSize == null){
                throw new IllegalAccessException("最大线程数必传");
            }
            return new ThreadConfig(this);
        }

        public ThreadConfig.Builder corePoolSize(int corePoolSize) {
            if (corePoolSize <= 0) {
                throw new IllegalArgumentException("核心线程数不能小于等于0");
            }
            this.corePoolSize = corePoolSize;
            return this;
        }

        public ThreadConfig.Builder threadName(String threadName) {
            this.threadName = threadName;
            return this;
        }


        public ThreadConfig.Builder maxPoolSize(int maxPoolSize) {
            if (maxPoolSize < this.corePoolSize) {
                throw new IllegalArgumentException("最大线程数不能小于核心线程数");
            }
            this.maxPoolSize = maxPoolSize;
            return this;
        }

        public ThreadConfig.Builder queueCapacity(int queueCapacity) {
            if (queueCapacity <= 0) {
                throw new IllegalArgumentException("队列不能小于等于0");
            }
            this.queueCapacity = queueCapacity;
            return this;
        }

        public ThreadConfig.Builder keepAliveTime(int keepAliveTime) {
            if (keepAliveTime <= 0) {
                throw new IllegalArgumentException("保持空闲线程可用的时间不能小于等于0");
            }
            this.keepAliveTime = keepAliveTime;
            return this;
        }

        public ThreadConfig.Builder allowCoreThreadTimeout(boolean allowCoreThreadTimeout) {
            this.allowCoreThreadTimeout = allowCoreThreadTimeout;
            return this;
        }
    }
}
